home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / hypercar / xcmd / dartxcmd.sit / Dartmouth XCMD's 3.1 / card_15752.txt < prev    next >
Encoding:
Text File  |  1989-06-02  |  10.4 KB  |  318 lines

  1. -- card: 15752 from stack: in.1
  2. -- bmap block id: 0
  3. -- flags: 0000
  4. -- background id: 3241
  5. -- name: Password
  6. ----- HyperTalk script -----
  7. on Install
  8.   get ChooseTargetStack()
  9.   InstallResource XFCN,Password,it
  10. end Install
  11.  
  12.  
  13. -- part 1 (button)
  14. -- low flags: 00
  15. -- high flags: A003
  16. -- rect: left=80 top=300 right=322 bottom=180
  17. -- title width / last selected line: 0
  18. -- icon id / first selected line: 0 / 0
  19. -- text alignment: 1
  20. -- font id: 0
  21. -- text size: 12
  22. -- style flags: 0
  23. -- line height: 16
  24. -- part name: Try It
  25. ----- HyperTalk script -----
  26. on mouseUp
  27.   put Password()
  28. end mouseUp
  29.  
  30.  
  31.  
  32. -- part 2 (field)
  33. -- low flags: 81
  34. -- high flags: 2007
  35. -- rect: left=12 top=26 right=298 bottom=491
  36. -- title width / last selected line: 0
  37. -- icon id / first selected line: 0 / 0
  38. -- text alignment: 0
  39. -- font id: 22
  40. -- text size: 10
  41. -- style flags: 0
  42. -- line height: 13
  43. -- part name: Source
  44.  
  45.  
  46. -- part 3 (button)
  47. -- low flags: 00
  48. -- high flags: A003
  49. -- rect: left=299 top=300 right=322 bottom=438
  50. -- title width / last selected line: 0
  51. -- icon id / first selected line: 0 / 0
  52. -- text alignment: 1
  53. -- font id: 0
  54. -- text size: 12
  55. -- style flags: 0
  56. -- line height: 16
  57. -- part name: Show Pascal Source
  58. ----- HyperTalk script -----
  59. on mouseUp
  60.   set the visible of card field 1 to not the visible of card field 1
  61.   if the visible of card field 1 is true then
  62.     set the name of me to "Hide Pascal Source"
  63.   else set the name of me to "Show Pascal Source"
  64. end mouseUp
  65.  
  66.  
  67.  
  68. -- part contents for background part 16
  69. ----- text -----
  70. PASSWORD XFCN version 1.0
  71. Kevin Calhoun
  72.  
  73. Password behaves in almost the same way as the HyperTalk command "ask password".  It differs in that it is capable of distinguishing between upper- and lower-case characters and in that it displays bullets in the ask dialog box instead of the actual password.  This is useful if you want to hide what you type from your little brother, your boss, or your archrival in software development.  
  74.  
  75. Password returns a number which it derives from the password that's entered.  This number can be stored in a field to be compared with the result of a subsequent call to Password if, for example, you want the user to be able to protect data contained in the stack.  Given a ne'er-do-well with access to enough CPU time or a whiz at 68000 opcodes with a good disassembler, it's not difficult to imagine that the encryption scheme that Password employs can be broken.  Use it only if your little brother, boss, or archrival in software development has better things to do than to hack your stack.
  76.  
  77. Note that the number returned by Password for a particular string is not the same as the number returned for that string by the HyperTalk command "ask password".
  78.  
  79. INVOKING PASSWORD
  80.  
  81. get Password(<"prompt">,<caseSensitive>)
  82.  
  83. result:  a number
  84.  
  85. If parameter 1 is present, it becomes the prompt string that appears in the same place as a question that's passed to the HyperTalk command ask.  If parameter 1 is not present, Password uses the prompt, "Please enter your password:". 
  86.  
  87. If caseSensitive is TRUE, then Password distinguishes between upper- and lower-case characters when encrypting the password.  If it is absent, or it is anything other than TRUE, Password does not distinguish between upper- and lower-case characters.
  88.  
  89. If an error occurs, Password returns a string, the first word of which will be "Error".  If the user clicks the Cancel button, Password returns "Cancel".  If the user types nothing before clicking the OK button, Password returns 0.
  90.  
  91. My thanks to Jim Matthews for the filter function that handles the bullets.
  92.  
  93. -- part contents for card part 2
  94. ----- text -----
  95. UNIT PasswordUnit;
  96.  
  97. { This source compatible with MPW Pascal 3.0 }
  98.  
  99. { Password XFCN ┬⌐1989 by the Trustees of Dartmouth College }
  100. { Written by Kevin Calhoun }
  101.  
  102. (*
  103. Pascal Password.p
  104. Link -m ENTRYPOINT Γêé
  105.      -o "YourFile" Γêé
  106.      -rt XFCN=17958 Γêé
  107.      -sn Main=Password Γêé
  108.      Password.p.o Γêé
  109.     "{Libraries}"interface.o Γêé
  110.     "{PLibraries}"Paslib.o Γêé
  111.     "{Libraries}"HyperXLib.o
  112. *)
  113.  
  114. {$R-}
  115.  
  116. INTERFACE
  117.   USES
  118.     Types,
  119.     Memory,
  120.     Resources,
  121.     Dialogs,
  122.     ToolUtils,
  123.     OSUtils,
  124.     HyperXCmd;
  125.  
  126.   PROCEDURE Entrypoint (paramPtr : XCmdPtr);
  127.  
  128. IMPLEMENTATION
  129.  
  130.   PROCEDURE DoPassword(paramPtr: XCMDPtr); FORWARD;
  131.  
  132.   PROCEDURE Entrypoint(paramPtr: XCMDPtr);
  133.   BEGIN
  134.     DoPassword(paramPtr);
  135.   END;
  136.   
  137.   FUNCTION GetScreenBitsBounds: Rect;
  138.   { get screenbits.bounds from the QuickDraw globals }
  139.   TYPE
  140.     LongwordPtr = ^LONGINT;
  141.     BitMapPtr = ^BitMap;
  142.   CONST
  143.     screenBitsOffset = -122;
  144.     CurrentA5 = $904;
  145.   VAR
  146.     screenBitsPtr : BitMapPtr;
  147.     myLongwordPtr : LongwordPtr;
  148.   BEGIN
  149.     myLongwordPtr := LongwordPtr(CurrentA5);
  150.       { myLongwordPtr now points to the pointer to the first QD global }
  151.     myLongwordPtr := LongwordPtr(myLongwordPtr^);
  152.       { myLongwordPtr now points to the first QD global }
  153.     screenBitsPtr := BitMapPtr(myLongwordPtr^ + screenBitsOffset);
  154.       { screenBitsPtr now points to the screenBits BitMap }
  155.     GetScreenBitsBounds := screenBitsPtr^.bounds;
  156.   END;
  157.     
  158.   PROCEDURE CenterRectH(var r: Rect; inRect: Rect);
  159.     var hOffset: INTEGER;
  160.   BEGIN
  161.     hOffset := ((inRect.right - inRect.left) - (r.right - r.left)) div 2;
  162.     OffsetRect(r, -r.left, 0);
  163.     OffsetRect(r, hOffset, 0);
  164.   END;
  165.  
  166.   FUNCTION Encrypt(s: Str255): LONGINT;
  167.   BEGIN
  168.     { insert your encryption routine here }
  169.   END;
  170.  
  171.   PROCEDURE PassReturnValue (paramPtr: XCMDPtr; s : Str255); { set theResult }
  172.   BEGIN
  173.     paramPtr^.returnValue := PasToZero(paramPtr, s);
  174.   END;
  175.  
  176.   { signonFilter -- dialog filter for doSignon, hides password }
  177.   FUNCTION SignonFilter (dp : DialogPtr;
  178.               VAR theEvent : EventRecord;
  179.               VAR itemHit : integer) : boolean;
  180.       CONST
  181.           nameItem = 3;
  182.           passwordItem = 4;
  183.           bs = $08;
  184.           tab = $09;
  185.           cr = $0D;
  186.           enter = $03;
  187.           larrow = $1C;
  188.           rarrow = $1D;
  189.           uparrow = $1E;
  190.           downarrow = $1F;
  191.       VAR
  192.           dpeek : DialogPeek;
  193.           theChar : char;
  194.           theStr : Str255;
  195.           selStart, selEnd : integer;
  196.           h : Handle;
  197.           itemType : integer;
  198.           box : Rect;
  199.           pwStr : StringPtr;
  200.   BEGIN
  201.       pwStr := StringPtr(GetWRefCon(dp));
  202.       signonFilter := false;
  203.       dpeek := DialogPeek(dp);
  204.       IF ((theEvent.what = keydown) OR (theEvent.what = autoKey)) THEN
  205.           BEGIN
  206.               theChar := char(BitAnd(theEvent.message, charCodeMask));
  207.               selStart := dpeek^.textH^^.selStart;
  208.               selEnd := dpeek^.textH^^.selEnd;
  209.               CASE ord(theChar) OF
  210.                   bs :                { Backspace }
  211.                       BEGIN
  212.                           IF selEnd = selStart THEN  { back over a character }
  213.                           BEGIN
  214.                               IF selStart > 0 THEN
  215.                                   pwStr^ := concat(copy(pwStr^,1, selStart - 1),
  216.                                                     copy(pwStr^, selStart + 1,
  217.                                                      length(pwStr^) - selStart));
  218.                           END
  219.                           ELSE            { delete the selection }
  220.                               pwStr^ := concat(copy(pwStr^, 1, selStart),
  221.                                copy(pwStr^, selEnd + 1, length(pwStr^) - selEnd));
  222.                       END;
  223.                   cr, enter :     { Return or Enter -- treat as "OK }
  224.                       BEGIN
  225.                           itemHit := ok;
  226.                           signonFilter := true;
  227.                       END; { cr, enter }
  228.                   tab, uparrow, downarrow, rarrow, larrow :
  229.                       ;        { just pass on tabs & arrows }
  230.                   OTHERWISE   { "normal" character }
  231.                       BEGIN        { remember character, insert a bullet }
  232.                           pwStr^ := concat(copy(pwStr^, 1, selStart), theChar,
  233.                            copy(pwStr^, selEnd + 1, length(pwStr^) - selEnd));
  234.                           theEvent.message := BitAnd(theEvent.message, $FFFFFF00) + ord('ΓÇó');
  235.                       END; { normal character }
  236.               END; { case ord(theChar) of }
  237.           END { in password field }
  238.           ELSE     { not in password field -- still check for cr, enter }
  239.               CASE BitAnd(theEvent.message, charCodeMask) OF
  240.                   cr, enter :
  241.                       BEGIN
  242.                           itemHit := ok;
  243.                           signonFilter := true;
  244.                       END; { cr, enter }
  245.                   OTHERWISE
  246.                       ;
  247.               END; { case BitAnd }
  248.   END; { signonFilter }
  249.   
  250.   PROCEDURE DoPassword(paramPtr: XCMDPtr);
  251.     var
  252.       h: Handle;
  253.       id: INTEGER;
  254.       rType: ResType;
  255.       s: Str255;
  256.       prompt: Str255;
  257.       pwStr: Str255;
  258.       itemHit: INTEGER;
  259.       d: DialogPtr;
  260.       myDialogTHndl : DialogTHndl;
  261.       kind: INTEGER;
  262.       r: Rect;
  263.       flag: BOOLEAN;
  264.       myLongint : LONGINT;
  265.       err: OSErr;
  266.   BEGIN
  267.     pwStr := '';
  268.     h := GetNamedResource('DLOG', 'Ask');
  269.     err := ResError;
  270.     if (h <> nil) and (err = noErr) then
  271.       begin
  272.       GetResInfo(h, id, rType, s);
  273.       if paramPtr^.paramCount > 0 then 
  274.         ZeroToPas(paramPtr, paramPtr^.params[1]^, prompt)
  275.       else prompt := 'Please enter your password:';
  276.       ParamText(prompt,'','','');
  277.       r := DialogTHndl(h)^^.boundsRect; { get DLOG boundsRect}
  278.       CenterRectH(r, GetScreenBitsBounds);
  279.       DialogTHndl(h)^^.boundsRect := r;
  280.       d := GetNewDialog(id, nil, POINTER(-1));
  281.       SetWRefCon(d, LONGINT(@pwStr));
  282.       ShowWindow(d);
  283.       BringToFront(d);
  284.       GetDItem(d, 1, kind, h, r);
  285.       SetPort(d);
  286.       InsetRect(r,-4,-4);
  287.       PenSize(3,3);
  288.       FrameRoundRect(r,16,16);
  289.       PenSize(1,1);
  290.       repeat
  291.         ModalDialog(@SignonFilter, itemHit);
  292.       until (itemHit = OK) or (itemHit = Cancel);
  293.       DisposDialog(d);
  294.       if itemHit = Cancel then
  295.         PassReturnValue(paramPtr, 'Cancel')
  296.       else
  297.         begin
  298.         if paramPtr^.paramCount > 1 then
  299.           begin
  300.           ZeroToPas(paramPtr, paramPtr^.params[2]^, s);
  301.           flag := FALSE;
  302.           flag := StrToBool(paramPtr, s);
  303.           if (paramPtr^.result <> noErr) or not flag then UprString(pwStr,TRUE);
  304.           end
  305.         else UprString(pwStr,TRUE);
  306.         myLongint := Encrypt(pwStr);
  307.         NumToStr(paramPtr, myLongint, s);
  308.         PassReturnValue(paramptr, s);
  309.         end;
  310.       end
  311.     else
  312.       begin
  313.       NumToStr(paramPtr, err, s);
  314.       PassReturnValue(paramPtr, CONCAT('Error ', s));
  315.       end;
  316.   END;
  317.  
  318. END.